package org.example.loader;

import lombok.SneakyThrows;
import org.example.state.GirlEyeState;
import org.springframework.core.io.support.SpringFactoriesLoader;

import javax.xml.bind.SchemaOutputResolver;
import java.io.IOException;
import java.io.InputStream;
import java.lang.invoke.MethodHandle;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.*;

/**
 * 类加载器是读取文件的文件流然后defineClass
 * 这样这个文件就可以在jvm了
 * 自定义的类加载器的父类加载器是系统类加载器app
 *
 * class.forName除了将.class文件加载进jvm,还会对类进行解释,执行类中的static块
 * classloader只是将.class文件加载进jvm,只有调用newInstance才会对类进行解释和执行static块
 */
public class TestLoader {
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, IOException {
        List<String> ids = new ArrayList<>();
        ids.add("ddd");
        ids.add("ddd");
        Set<String> idss = new LinkedHashSet<>(ids);
        System.out.println(idss);
        String ddd = "META-INF/spring.factories";
        String fff = "jb.txt";

        System.out.println("/ddd".substring(1));
        Enumeration<URL> resources1 = SpringFactoriesLoader.class.getClassLoader().getResources(fff);
        Enumeration<URL> resources = SpringFactoriesLoader.class.getClassLoader().getResources(ddd);
        System.out.println(TestLoader.class.getResource("/").toString());
        System.out.println(TestLoader.class.getResource("").toString());
        System.out.println(ClassLoader.getSystemClassLoader().getResource("/"));
        System.out.println(ClassLoader.getSystemClassLoader().getResource(""));
        System.out.println(Thread.currentThread().getContextClassLoader().getResource("/"));
        System.out.println(Thread.currentThread().getContextClassLoader().getResource(""));
        System.out.println(ClassLoader.getSystemClassLoader());
        System.out.println(ClassLoader.getSystemClassLoader().getParent());
        System.out.println(ClassLoader.getSystemClassLoader().getParent().getParent());

        //查看当前系统类路径包含的路径条目
        System.out.println(System.getProperty("java.class.path"));
        Class<?> aClass = Class.forName("org.example.state.GirlEyeState");
        System.out.println(aClass.getClassLoader());
        GirlEyeState o = (GirlEyeState) aClass.newInstance();
        //o.handle(null);

        ClassLoader c = new ClassLoader() {
            @SneakyThrows
            @Override
            public Class<?> loadClass(String name) throws ClassNotFoundException {
                String filename = name.substring(name.lastIndexOf(".") + 1)
                        + ".class";
                InputStream is = getClass().getResourceAsStream(filename);
                if (is == null) {
                    return super.loadClass(name);   // 递归调用父类加载器
                }
                byte[] b = new byte[is.available()];
                is.read(b);
                return defineClass(name, b, 0, b.length);
            }
        };
        System.out.println(c.getParent());
    }
}
